#include <iostream>

#include "objectmpi/objectmpi.h"
#include <mpi.h>

#include <unistd.h> // sleep()

using namespace std;

class MySlave : public Slave{

	public:		
		void JobHandler(char* inputBuffer, int size){
			printf("Rank%d: Wykonywanie 10 sekundowego zadania...\n", slaveId);			
			// sleep(10);
			// sprintf(inputBuffer, "Wiadomosc od niewolnika: witaj panie!");
		}
		
};

class MyMaster : public Master{
	
};



int main(int argc, char *argv[]){
	int pool_size, my_rank, namelen;

	MPI_Init(&argc, &argv);
	MPI_Comm_size(MPI_COMM_WORLD, &pool_size);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
	
	char pr_name[MPI_MAX_PROCESSOR_NAME];
	MPI_Get_processor_name(pr_name, &namelen);
	
	printf("Initialized node %s (%d of %d)\n", pr_name, my_rank, pool_size);

	int bufferSize = 2048; // rozmiar wiadomosci wysylanych miedzy nodami
	char* buffer = new char[bufferSize]; // bufor do przesylania wiadomosci
	
	if (my_rank==0){
		MPI_Request request;
		MPI_Status status;				
		
		MyMaster* master = new MyMaster();
		master->SetParameters(buffer, bufferSize);
		
		// Ustawienie bufora slave 1 na wartosc zmiennej bufferSize
		// master->SendSetBufferSize(1, bufferSize);
		
		
		// Wyslanie komunikatu do wykonania zadania 10-sekundowego
		master->SendJob(1, buffer, bufferSize);
		
		
		// Przerwanie zadania 10-sekundowego po 3 sekundach
		// sleep(3);
		// master->SendCloseAllThreads(1);		
		
		
		// Ponowny komunikat do wykonania zadania 10-sekundowego
		// master->SendJob(1, buffer, bufferSize);
		
		// Tym razem wywolanie polecania synchronizujacego watki w Slavie (blokujace)
		master->SendSync(1);
		
		// Odebranie widomosci od Slave
		master->Receive(1, buffer, bufferSize);
		printf("Master: Received >> %s <<\n", buffer);		
		
		
		
		// Wylaczenie calego Slave'a		
		master->SendTerminateSlave(1);
		sleep(1);
	}
	
	// Slaves
	if (my_rank!=0){

		MySlave* mySlave = new MySlave();
		mySlave->SetParameters(my_rank, bufferSize);
		mySlave->Start();
		
	}
		
	printf("Node %d MPI_Finalize()\n", my_rank);
	MPI_Finalize();
}
